#include "Database.hpp"
#include "sqlite3x.hpp"
#include "sqlite3.h"
#include "../sniffer_class_defs.hpp"
#include <stdlib.h>
#include <string.h>
#include <stdio.h>


/*******************************************************************
Variables for Database Functionality

int em - This variable is the storage for the return result from a SQL operation. A result of 0 is a SQLITE_OK return and indicates a successful command.
sqlite3 *conn - This variable is the connection handle to the database. Once CreateDb() or OpenConnection() is called this is set to the connection handle.

*/

int em;
sqlite3 *conn = NULL; //connection handle
sqlite3_stmt *stmt = NULL; //table fetching handle (most likely no need to implament, for prepaired statements)



/*******************************************************************
* NAME :			Callback()
*
* DESCRIPTION :     This function is the callback function to retrieve the information from the SELECT
*
* Inputs : None
*
* OUTPUTS : void
*
* NOTES : This function was taken from sqlite3.com as the standard callback function, but was slightly modified to only return the data requested without the column header
*
* CHANGES :
*
* Programmer : Kevin Fuhrman
*/

static int Callback(void *NotUsed, int argc, char **argv, char
**azColName){
  int i;
  for(i=0; i<argc; i++){
    //printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL"); original statement
    printf("%s\n", argv[i] ? argv[i] : "NULL");
  }
  printf("\n");
  return 0;
}

/*******************************************************************
* NAME :			CreateDb()
*
* DESCRIPTION :     This function will create a database and initialize the table in the proper format.
*
* Inputs : None
*
* OUTPUTS : void
*
* NOTES :
*
* CHANGES :
*
* Programmer : Kevin Fuhrman
*/

int CreateDb(const char *dbname)
{

	em = sqlite3_open(dbname, &conn);

	if (em !=0)
	{
		return SQLITE_ERROR;
	}
	sqlite3_exec(conn, "CREATE TABLE packets (packnum integer primary key, source BLOB, destination BLOB, type BLOB, stream BLOB);",0,0,0);

	return SQLITE_OK;

}

/*******************************************************************
* NAME :			OpenConnection()
*
* DESCRIPTION :  This function will open a connection with the Sqlite3 database.
*
* Inputs : None
*
* OUTPUTS : Returns a 0 if successful, otherwise returns an error number.
*
* NOTES :
*
* CHANGES :
*
* Programmer : Kevin Fuhrman
*/

int OpenConnection(const char *name)
{
	em = sqlite3_open(name, &conn);
	if (em !=0)
	{
		return SQLITE_ERROR;
	}

    return SQLITE_OK;
}

/*******************************************************************
* NAME :			CloseConnection()
*
* DESCRIPTION :     This function will close an open connection with the Sqlite3 database.
*
* Inputs : 			None
*
* OUTPUTS : 		Returns a 0 if successful, otherwise returns an error number
*
* NOTES :
*
* CHANGES :
*
* Programmer : 		Kevin Fuhrman
*/

int CloseConnection()
{

	em = sqlite3_close(conn);
	if (em !=0)
		{
			return SQLITE_ERROR;
		}

    return SQLITE_OK;
}

/*******************************************************************
* NAME :			Insert()
*
* DESCRIPTION :     This function will insert data into the table in the database.
*
* Inputs : 			None
*
* OUTPUTS : 		void
*
* NOTES :
*
* CHANGES :
*
* Programmer : 		Kevin Fuhrman
*/

int Insert(const char * source, const char * dest, const char * type, const char *adv_info)
{

	char str0[100];
	char str1[] = "INSERT INTO packets values (NULL, ";
	char str2[] = ");";
	char str3[] = ", ";
	char str4[] = "\"";
	

	std::string a = "" + ((std::string)source) + "";
	std::string b = "" + ((std::string)dest) + "";
	std::string c = "" + ((std::string)type) + "";

	sprintf(str0, "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", str1, str4, a.c_str(), str4, str3, str4, b.c_str(), str4, str3, str4, c.c_str(), str4, str3, str4, adv_info, str4, str2);

	sqlite3_exec(conn,"BEGIN",0,0,0);
	em = sqlite3_exec(conn,str0,0,0,0);
	sqlite3_exec(conn,"COMMIT",0,0,0);

	return em;
}

/*******************************************************************
* NAME :			RetrievePacket(char packnum)
*
* DESCRIPTION :     This function will select a database entry to display in the expanded details window of the gui.
*
* Inputs : 			None
*
* OUTPUTS : 		void
*
* NOTES :
*
* CHANGES :
*
* Programmer : 		Kevin Fuhrman
*/

int RetrievePacket(char packnum[])
{
	char str1[50] = "SELECT bitstream FROM packets WHERE packnum = ";

	strcat(str1,packnum);
	em = sqlite3_exec(conn,str1, Callback, 0, 0);

	return em;
}

/*******************************************************************
* NAME :			RestoreSession()
*
* DESCRIPTION :     This function will select a database entry to display in the expanded details window of the gui.
*
* Inputs : 			None
*
* OUTPUTS : 		void
*
* NOTES :			TO DO ONCE GUI IS CLOSER TO IMPLEMENTATION
*
* CHANGES :
*
* Programmer : 		Kevin Fuhrman
*/

int RestoreSession()
{
//	int identifier;
//	char source[];
//	char destination[];
//	int protocol;
	/*

	char str1[50] = "SELECT packnum FROM packets WHERE packnum = ";
	char str2[50] = "SELECT source FROM packets WHERE packnum = ";
	char str3[50] = "SELECT destination FROM packets WHERE packnum = ";
	char str4[50] = "SELECT type FROM packets WHERE packnum = ";

	strcat(str1,packnum);
	em = sqlite3_exec(conn,str1, Callback, 0, 0);
	indentifier = (int) em;

	strcat(str2,packnum);
	em = sqlite3_exec(conn,str1, Callback, 0, 0);
	source = em;

	strcat(str3,packnum);
	em = sqlite3_exec(conn,str1, Callback, 0, 0);
	destination = eml

	strcat(str4,packnum);
	em = sqlite3_exec(conn,str1, Callback, 0, 0);
	protocol = (int) em;
	
	addIncoming(
	*/ 
	return 0;
}

